package basicx.oop.lifecyclex

/**
主构造函数里声明的属性
类级别的属性赋值
init初始化块里的属性赋值和函数调用
次构造函数里的属性赋值和函数调用
 */
private class InitClass(
//    主构造
    var name: String = "MR",//给予默认值

    /**Kotlin允许你不使用临时变量赋值，而是直接用一个定义同时指定参数和类属性，通
    常，我们更喜欢用这种方式定义类属性，因为他会减少重复代码。
     */
    private var _age: Int,
) {

    var age = _age//仅仅使用一次的变量，_开头

    /**lateinit关键字相当于做了一个约定:在用它之前负责初始化
    只要无法确认lateinit变量是否完成初始化，可以执行isInitialized检查
     */
    lateinit var subject: String//延迟初始化,必须调用赋值，才可以后续使用，否则报错
    fun useLateInit() {
        subject = "lateinit"
        if (::subject.isInitialized) {
            println("lateinit:${subject}")
        }
    }

    /**延迟初始化并不是推后初始化的唯一方式，你也可以暂时不初始化某个变量，直到首
    次使用它,这个叫作惰性初始化。
     */
    val lazy by lazy { loadConfig()/*后续执行*/ }// val,懒汉式,用时才加载
    val lazyx = lazy { loadConfig() }  // 开局初始化


    fun loadConfig(): String {
        println("........loading lazy.........")
        return "xxx"
    }

    /**初始化块可以设置变量或值，以及执行有效性检查，如检查传给某构造函数的值是否
    有效，初始化块代码会在构造类实例时执行。
     */
    init { // 主--类--块(int)--次
        //kotlin 编译具有顺序,不能写反
        // 参验证
        require(age > 0) { "age must be positive" }
        require(name.isNotBlank()) { "player must be a name" }
        println("lazyx.value ${lazyx.value}")
    }
}


private  fun main() {
    var ic = InitClass("HH", 12)
    ic.useLateInit()
    println("======")
    ic.lazy // 使用时初始化

}